﻿using Newtonsoft.Json.Linq;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace MYQQX
{
    public class GroupConfig
    {
        public static GroupConfig Instance { get; private set; } = new GroupConfig();
        private GroupConfig() { }

        public List<ScoreGroup> groups { get; private set; }

        public void Init()
        {
            groups = new List<ScoreGroup>() ;
            var configJson = Properties.Resources.ComboJson;

            JArray json = JArray.Parse(configJson);

            foreach (JArray com in json)
            {
                ScoreGroup sg = new ScoreGroup() 
                {
                    groups = com[0].ToObject<string[]>(),
                    Name = com[1].ToString(),
                    Score = com[2].ToObject<int>()
                };

                groups.Add(sg);
            }
        }

        internal List<ScoreGroup> GetGroups(IEnumerable<Card> nCard)
        {
            return groups.Where(t => t.groups.Intersect(nCard.Select(nt => nt.Name)).Count() == t.groups.Count()).ToList();
        }

        internal bool CanGroup(Card card, Card cd)
        {
            throw new NotImplementedException();
        }

        internal string GetTips(string name)
        {
            StringBuilder sb = new StringBuilder();
            sb.AppendLine("组合卡牌：");
            foreach (var gp in groups)
            {
                if (gp.groups.Contains(name))
                {
                    var need = gp.groups.ToList();
                    sb.AppendLine($"{gp.Name}[{gp.Score}]: " + string.Join(",", need));
                }
            }

            return sb.ToString();
        }

        internal List<ScoreGroup> MatchGroup(Card card)
        {
            return this.groups.Where(t => t.groups.Contains(card.Name)).ToList();
        }

        internal Dictionary<string, SuggestInfo> Suggest(CardGroup _group)
        {
            Dictionary<string, SuggestInfo> sg = new Dictionary<string, SuggestInfo>();
            List<ScoreGroup> mGroups = new List<ScoreGroup>();
            foreach (var card in _group.cardList)
            {
                mGroups.AddRange(GroupConfig.Instance.MatchGroup(card));
            }
            var iGps = mGroups.Distinct();
            var hcs = _group.cardList.Select(t => t.Name).ToList();
            foreach (var gp in iGps)
            {
                var cards = gp.groups.ToList();
                cards.RemoveAll(t => hcs.Contains(t));
                if (cards.Count > 0)
                {
                    foreach (var cd in cards)
                    {
                        if (sg.TryGetValue(cd, out SuggestInfo si))
                        {
                            si.gps.Add(gp);
                            si.sNum += (1.0 / cards.Count);
                        }
                        else
                        {
                            si = new SuggestInfo()
                            {
                                cName = cd,
                                gps = new List<ScoreGroup>() { gp },
                                sNum = 1.0 / cards.Count
                            };
                            sg.Add(cd, si);
                        }
                    }
                }
            }
            sg = sg.OrderByDescending(t => t.Value.sNum).ThenByDescending(t => t.Value.gps.Count)
                .ToDictionary(k => k.Key, v => v.Value);

            var keys = sg.Keys.ToList();
            if (keys.Count > 10)
            {
                var dels = keys.Skip(10);
                foreach (var de in dels)
                    sg.Remove(de);
            }
            return sg;

        }
    }
}
